package com.ai.networking.netty.service;

import com.ai.entity.network.HeartMessage;
import com.ai.entity.network.L2ToDsSysMessage;
import com.ai.entity.network.SiToDsSysMessage;
import com.ai.networking.netty.comm.CommonNetty;
import com.ai.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;

@Slf4j
public class SendMessage {
    public static void sendMessage(String code, Object msg) {
        log.info("===========================  客户端code：{} ===========================",code);
        log.info("===========================  发送消息内容:{} ===========================", JSONObject.toJSONString(msg));
        byte[] message =new byte[256];
        if (msg instanceof HeartMessage){
            HeartMessage heartMessage = (HeartMessage) msg;
            message = createHeart(heartMessage);
        } else if (msg instanceof L2ToDsSysMessage){
            L2ToDsSysMessage l2ToDsSysMessage = (L2ToDsSysMessage) msg;
            message = createDSSI01(l2ToDsSysMessage,code);
        }else if (msg instanceof SiToDsSysMessage){
            SiToDsSysMessage siToDsSysMessage = (SiToDsSysMessage) msg;
            message = createDSAG(siToDsSysMessage);
        }
        log.info("===========================  报文组建完毕：{}  ===========================",new String(message));
        Channel channel = CommonNetty.ctxMap.get(code).channel();
        log.info("===========================  开始发送报文  ===========================");
        channel.writeAndFlush(Unpooled.copiedBuffer(message));
        channel.flush();
        log.info("===========================  报文发送完毕  ===========================");
    }

    /**
     * 心跳信息下发
     * @param 
     * @return
     */
    public static byte[] createHeart(HeartMessage heartMessage) {
        log.info("===========================  发送消息原内容：{}  ===========================",JSONObject.toJSONString(heartMessage));
        log.info("===========================  开始组建消息  ===========================");
        Integer messageLength=256;
        String length = heartMessage.getLength();
        String teleNo = heartMessage.getTeleNo();
        String spare = heartMessage.getSpare();

        byte[] messageBytes = new byte[messageLength];
        // 1. 消息长度：4字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(length,4), 0);

        // 2. 电文号：6字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(teleNo, 6), 4);
        
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(spare,156), 10);

        log.info("=========================== 消息组件完毕：  ===========================");
        log.info("=========================== ## BootNettyClientChannelCache.createMessageToPlcOther  end ##  ===========================");

        return messageBytes;
    }

    /**
     * DSSI01 钢卷信息下发
     * @param l2ToDsSysMessage
     * @return
     */
    public static byte[] createDSSI01(L2ToDsSysMessage l2ToDsSysMessage,String code) {
        log.info("===========================  发送消息原内容：{}  ===========================",JSONObject.toJSONString(l2ToDsSysMessage));
        log.info("===========================  开始组建消息  ===========================");
        Integer messageLength=256;
        String length = l2ToDsSysMessage.getLength();
        String teleNo = "DSSI01";
        if (code.equals("AG_C")){
            teleNo = "DSAG01";
        }
        String coilNo = l2ToDsSysMessage.getCoilNo();
        String lengthMm = l2ToDsSysMessage.getLengthMm().toString();
        String width = l2ToDsSysMessage.getWidth().toString();
        BigDecimal thickness = l2ToDsSysMessage.getThickness();
        String steelGrade = l2ToDsSysMessage.getSteelGrade();
        String sortingGrade = l2ToDsSysMessage.getSortingGrade();
        String workOrderNo = l2ToDsSysMessage.getWorkOrderNo();
        String orderQuality = l2ToDsSysMessage.getOrderQuality();
        String finalUse = l2ToDsSysMessage.getFinalUse();
        String finalUser = l2ToDsSysMessage.getFinalUser();
        String dummy = l2ToDsSysMessage.getDummy();
        String surfStrucCode = l2ToDsSysMessage.getSurfStrucCode();
        String postProc = l2ToDsSysMessage.getPostProc();
        String spare = l2ToDsSysMessage.getSpare();

        
        byte[] messageBytes = new byte[messageLength];
        // 1. 消息长度：4字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(length,4), 0);
        
        // 2. 电文号：6字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(teleNo, 6), 4);

        // 3. 钢卷号：16字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(coilNo,16), 10);

        // 4. 长度：6字节，3位小数
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(lengthMm, 8), 26);

        // 5. 宽度：6字节，1位小数
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(width, 6), 34);

        // 6. 厚度：12字节，3位小数
        StringUtil.byteInsert(messageBytes, StringUtil.convertBigDecimalToHex(thickness, 6,3), 40);

        // 7. 出钢记号：8字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(steelGrade, 8), 46);

        // 8. 分选度：2字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(sortingGrade,2), 54);

        // 9. 生产合同号：10字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(workOrderNo, 10), 56);

        // 10. 钢种牌号：20字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(orderQuality, 20), 66);

        // 11. 最终用途：4字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(finalUse,4), 86);

        // 12. 最终用户代码：6字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(finalUser,6), 90);

        // 13. 过渡卷标志：2字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(dummy,2), 96);

        // 14. 表面结构：4字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(surfStrucCode,4), 98);

        // 15. 后处理方式：4字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(postProc,4), 102);

        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(spare,150), 106);

        log.info("=========================== 消息组件完毕：  ===========================");
        log.info("=========================== ## BootNettyClientChannelCache.createMessageToPlcOther  end ##  ===========================");

        return messageBytes;
    }

    /**
     * DSAG02 缺陷检测系统状态
     * @param siToDsSysMessage
     * @return
     */
    public static byte[] createDSAG(SiToDsSysMessage siToDsSysMessage) {
        log.info("===========================  发送消息原内容：{}  ===========================",JSONObject.toJSONString(siToDsSysMessage));
        log.info("===========================  开始组建消息  ===========================");
        // 设定消息长度为 256
        Integer messageLength = 256;

        // 提取消息中的各个字段
        String length = siToDsSysMessage.getLength();
        String teleNo = siToDsSysMessage.getTeleNo();
        String coilNo = siToDsSysMessage.getCoilNo();
        String faultState = siToDsSysMessage.getFaultState();
        String defect = siToDsSysMessage.getDefect();
        String straightDeviation = siToDsSysMessage.getStraightDeviation();
        String spare = siToDsSysMessage.getSpare();



        // 创建一个固定长度的字节数组，长度为256
        byte[] messageBytes = new byte[messageLength];

        // 1. 电文长度：4字节，填充为4
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(length,4), 0);

        // 2. 电文号：6字节
        StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(teleNo, 6), 4);

        if (faultState != null){
            StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(faultState,100), 10);
            StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(spare, 146), 110);
        }else if (defect != null){
            StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(coilNo, 16), 10);
            StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(defect,2), 26);
            StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(spare, 228), 28);
        }else if (straightDeviation != null){
            StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(coilNo, 16), 10);
            StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(straightDeviation,10), 26);
            StringUtil.byteInsert(messageBytes, StringUtil.convertStringToHex(spare, 220), 36);
        }
        log.info("=========================== 消息组件完毕：  ===========================");
        log.info("=========================== ## BootNettyClientChannelCache.createMessageToPlcOther  end ##  ===========================");

        return messageBytes;
    }
}
